/**
 * @fileoverview This is a file where undefinedVars checks are disabled.
 * @suppress {undefinedVars}
 */
// the above is for the Google Closure Compiler ant task

function Buffer()
{
    this.ships = [];
//    this.oppShips = []; //temp
//    this.oppDone = true;
    this.startingPlayer = false;
//    this.shotsToGo = []; //temp
//    this.oppShotsToGo = []; //temp
//    this.allOppShots = []; //temp

    this.sendShips = sendShips;
//    this.opponentDone = opponentDone;
//    this.genStartingPlayer = genStartingPlayer; //temp
//    this.genOppShips = genOppShips; //temp
    this.shoot = shoot;
    this.oppShoot = oppShoot; //temp
//    this.genOppShot = genOppShot; //temp
//    this.gameOver = gameOver;
//    this.genAllOppShots = genAllOppShots;
}

// initialize the buffer
var buff = new Buffer();

/** @suppress {duplicate} */
function heartbeat() {
//    var id = localStorage.getItem("id");
    var token = localStorage.getItem("token");

//    $.get("heartbeat", {"id":id},
    $.get("heartbeat", {"token":token},
        function() {
            setTimeout("heartbeat()", 5000);
        });
}

//function sendShips(shipArray) {
//    this.ships = $.extend(true, [], shipArray);
//    this.shotsToGo = $.extend(true, [], shipArray); //temp
//    this.genAllOppShots();
//    if (this.oppDone) {
//        this.genStartingPlayer(); //temp
//        this.genOppShips(); //temp
//        this.shotsToGo = $.extend(true, [], this.oppShips);
//        this.oppShotsToGo = $.extend(true, [], this.ships);
//        env.startGame();
//    } else {
//        alert("Vastane pole veel oma laevade paigutamist lõpetanud. Palun oota.");
//        this.genStartingPlayer(); //temp
//        this.genOppShips(); //temp
//        this.shotsToGo = $.extend(true, [], this.oppShips);
//        this.oppShotsToGo = $.extend(true, [], this.ships);
//        setTimeout("env.startGame()",3000); //temp
//    }
//}

function sendShips(shipArray) {
    // encode ship locations
    var ships = "";
    var firstShip = shipArray[0];
    var firstCoord1 = firstShip[0];
    ships = ships + firstCoord1[0] + "," + firstCoord1[1];
    for (var i = 1; i < firstShip.length; i++) {
        ships = ships + ";" + firstShip[i][0] + "," + firstShip[i][1];
    }
    for (var j = 1; j < shipArray.length; j++) {
        ships = ships + ".";
        var ship = shipArray[j];
        var firstCoord = ship[0];
        ships = ships + firstCoord[0] + "," + firstCoord[1];
        for (var k = 1; k < ship.length; k++) {
            ships = ships + ";" + ship[k][0] + "," + ship[k][1];
        }
    }
    console.log("the ship locations are: " + ships);
//    $.post("sendShips", {ships: ships, "id":localStorage.getItem("id")},
    $.post("sendShips", {ships: ships, "token":localStorage.getItem("token")},
    function(data) {
        buff.startingPlayer = data.startingPlayer;
        if (data.opponentFinished) {
            env.startGame();
        } else {
            alert("Vastane pole veel lõpetanud oma laevade paigutamist. Palun oota.");
            $("#valmis").css("visibility", "hidden");
            // wait for opponent using long polling
//            $.get("sendShips", {"id":localStorage.getItem("id")},
            $.get("sendShips", {"token":localStorage.getItem("token")},
            function() {
                env.startGame();
            });
        }

    }, "json");
}

//function genAllOppShots() {
//    for (var i = 1; i < 11; i++){
//        for (var j = 1; j < 11; j++) {
//            this.allOppShots.push([i,j]);
//        }
//    }
//}

//function genStartingPlayer() {
//    // temp
//    // randomly generate starting player
//    var x = Math.random();
//    this.startingPlayer = x > 0.5 ? true : false;
//}

//function genOppShips() {
//    //randomly generate the opponent's ships locations
//
//    var startRow;
//    var startCol;
//    var ship = [];
//
//    //generate ship with length 4:
//    var horizontal = Math.random() > 0.5 ? true : false;
//    if (horizontal) {
//        startRow = Math.floor(Math.random()*10+1);
//        startCol = Math.floor(Math.random()*7+1);
//        ship.push([startRow,startCol]);
//        for (var i = 1; i <= 3; i++) {
//            ship.push([startRow,startCol+i]);
//        }
//    } else {
//        startRow = Math.floor(Math.random()*7+1);
//        startCol = Math.floor(Math.random()*10+1);
//        ship.push([startRow,startCol]);
//        for (var i = 1; i <= 3; i++) {
//            ship.push([startRow+i,startCol]);
//        }
//    }
//    this.oppShips.push(ship);
//    ship = [];
//    //console.log("the first ship is: " + this.oppShips);
//
//    //generate two ships with length 3
//    var count = 0;
//    while (count < 2) {
//        var legal = true;
//        horizontal = Math.random() > 0.5 ? true : false;
//        if (horizontal) {
//            startRow = Math.floor(Math.random()*10+1);
//            startCol = Math.floor(Math.random()*8+1);
//            ship.push([startRow,startCol]);
//            for (var i = 1; i <= 2; i++) {
//                ship.push([startRow,startCol+i]);
//            }
//        } else {
//            startRow = Math.floor(Math.random()*8+1);
//            startCol = Math.floor(Math.random()*10+1);
//            ship.push([startRow,startCol]);
//            for (var i = 1; i <= 2; i++) {
//                ship.push([startRow+i,startCol]);
//            }
//        }
//        outer: for each (coord in ship) {
//            for each (setShip in this.oppShips) {
//                for each (setCoord in setShip) {
//                    if (coord[0] >= setCoord[0]-1 && coord[0] <= setCoord[0]+1 && coord[1] >= setCoord[1]-1 && coord[1] <= setCoord[1]+1) {
//                        //console.log("the ship " + ship + " is inadequate");
//                        //console.log("coords: " + coord[0] + ", " + coord[1] + " checked against " + setCoord[0] + ", " + setCoord[1]);
//                        legal = false;
//                        break outer;
//                    }
//                }
//            }
//        }
//        if (legal) {
//            this.oppShips.push(ship);
//            count++;
//        }
//        ship = [];
//    }
//    //console.log("ships so far: " + this.oppShips);
//
//    // generate 3 ships with length 2
//    count = 0;
//    while (count < 3) {
//        legal = true;
//        horizontal = Math.random() > 0.5 ? true : false;
//        if (horizontal) {
//            startRow = Math.floor(Math.random()*10+1);
//            startCol = Math.floor(Math.random()*9+1);
//            ship.push([startRow,startCol]);
//            ship.push([startRow,startCol+1]);
//        } else {
//            startRow = Math.floor(Math.random()*9+1);
//            startCol = Math.floor(Math.random()*10+1);
//            ship.push([startRow,startCol]);
//            ship.push([startRow+1,startCol]);
//        }
//        outer: for each (coord in ship) {
//            for each (setShip in this.oppShips) {
//                for each (setCoord in setShip) {
//                    if (coord[0] >= setCoord[0]-1 && coord[0] <= setCoord[0]+1 && coord[1] >= setCoord[1]-1 && coord[1] <= setCoord[1]+1) {
//                        //console.log("the ship " + ship + " is inadequate");
//                        //console.log("coords: " + coord[0] + ", " + coord[1] + " checked against " + setCoord[0] + ", " + setCoord[1]);
//                        legal = false;
//                        break outer;
//                    }
//                }
//            }
//        }
//        if (legal) {
//            this.oppShips.push(ship);
//            count++;
//        }
//        ship = [];
//    }
//    //console.log("ships so far: " + this.oppShips);
//
//    // generate 4 ships with length 1
//    count = 0;
//    while (count < 4) {
//        legal = true;
//        horizontal = Math.random() > 0.5 ? true : false;
//        if (horizontal) {
//            startRow = Math.floor(Math.random()*10+1);
//            startCol = Math.floor(Math.random()*10+1);
//            ship.push([startRow,startCol]);
//        } else {
//            startRow = Math.floor(Math.random()*10+1);
//            startCol = Math.floor(Math.random()*10+1);
//            ship.push([startRow,startCol]);
//        }
//        outer: for each (coord in ship) {
//            for each (setShip in this.oppShips) {
//                for each (setCoord in setShip) {
//                    if (coord[0] >= setCoord[0]-1 && coord[0] <= setCoord[0]+1 && coord[1] >= setCoord[1]-1 && coord[1] <= setCoord[1]+1) {
//                        //console.log("the ship " + ship + " is inadequate");
//                        //console.log("coords: " + coord[0] + ", " + coord[1] + " checked against " + setCoord[0] + ", " + setCoord[1]);
//                        legal = false;
//                        break outer;
//                    }
//                }
//            }
//        }
//        if (legal) {
//            this.oppShips.push(ship);
//            count++;
//        }
//        ship = [];
//    }
//    console.log("ships so far: " + this.oppShips);
//}

//function opponentDone() {
//    this.oppDone = true;
//    alert("Vastane lõpetas oma laevade paigutamise.");
//}

//function shoot(cell) {
//    var col = cell.cellIndex;
//    var row = cell.parentNode.rowIndex;
//    //console.log("row: " + row + ", col: " + col);
//    var hit = false;
//    console.log("shots to go: " + this.shotsToGo);
//    outer: for (var i = 0; i < this.shotsToGo.length; i++) {
//        //console.log("currently looking at ship: " + this.shotsToGo[i] + " with length " + this.shotsToGo[i].length );
//        for (var j = 0; j < this.shotsToGo[i].length; j++) {
//            //console.log("looking at coordinate: " + this.shotsToGo[i][j]);
//            if (row == this.shotsToGo[i][j][0] && col == this.shotsToGo[i][j][1]) {
//                console.log("it's a hit!");
//                // it's a hit
//                hit = true;
//                this.shotsToGo[i].splice(j,1);
//                console.log("current ship left: " + this.shotsToGo[i]);
//                if (this.shotsToGo[i].length == 0) {
//                    // the entire ship is destroyed
//                    env.markCell(cell,1);
//                    this.shotsToGo.splice(i,1);
//                } else {
//                    // only part of the ship is destroyed
//                    env.markCell(cell,2);
//                }
//                if (this.gameOver(this.shotsToGo)) { env.finishGame(1); } else { env.yourTurn(); }
//                break outer;
//            }
//        }
//    }
//    if (!hit) {
//        env.markCell(cell,3);
//        env.oppTurn();
//    }
//}

function shoot(coords) {
    var shot = coords[0] + "," + coords[1];
//    $.post("shoot", {shot: shot, "id":localStorage.getItem("id")},
    $.post("shoot", {shot: shot, "token":localStorage.getItem("token")},
    function(data) {
        console.log("shoot(): the result is " + data.result + ", " + data.coordPairs);

        var result = data.result;
        var coordPairs = data.coordPairs; // int[][], coordinates of the cells to be marked

        // mark the cell(s)
        if (result === "miss") {
            saveShooting(coords[1], coords[0], 3, 0);   // for replay (localStorage)
            new Audio("sounds/splash.wav").play();
            var coordPair = coordPairs[0];
            markCell(coordPair, 3);
            env.oppTurn();
        } else if (result === "hit") {
            saveShooting(coords[1], coords[0], 2, 0);   // for replay (localStorage)
            new Audio("sounds/thump.wav").play();
            var coordPair = coordPairs[0];
            markCell(coordPair, 2);
            env.yourTurn();
        } else if (result === "sink") {
            saveShooting(coords[1], coords[0], 1, 0);   // for replay (localStorage)
            new Audio("sounds/explosion.wav").play();
            for (i = 0; i < coordPairs.length; i++) {
                var coordPair = coordPairs[i];
                if (coordPair[0] === coords[0] && coordPair[1] === coords[1]) {
                    // it's the original cell, needs a picture and to be coloured
                    markCell(coordPair,1);
                } else {
                    // cell already has a picture, needs to be coloured
                    markCell(coordPair, 4);
                }
            }
            env.yourTurn();
        }




//        var put = false;
//        if (result == "sink") {
//            outer: for each (ship in buff.oppShips) {
//                for each (coord in ship) {
//                    if ((x <= coord[0]+1 && x >= coord[0]-1) && (y >= coord[1]-1 && y <= coord[1]+1)) {
//                        ship.splice(0,1,[x,y]);
//                        put = true;
//                        break outer;
//                    }
//                }
//            }
//            if (!put) {
//                buff.oppShips.splice(0,1,[[x,y]]);
//            }
//            markCell(cell, 1);
//            env.yourTurn();
//        } else if (result == "hit") {
//            outer: for each (ship in buff.oppShips) {
//                for each (coord in ship) {
//                    if ((x <= coord[0]+1 && x >= coord[0]-1) && (y >= coord[1]-1 && y <= coord[1]+1)) {
//                        ship.splice(0,1,[x,y]);
//                        put = true;
//                        break outer;
//                    }
//                }
//            }
//            if (!put) {
//                buff.oppShips.splice(0,1,[[x,y]]);
//            }
//            markCell(cell, 2);
//            env.yourTurn();
//        } else {
//            console.log("going to mark cell with miss");
//            markCell(cell, 3);
//            env.oppTurn();
//        }




    }, "json");
}



function oppShoot() {
    // use long polling here to wait for and get opponent's shot
//    $.get("shoot", {"id":localStorage.getItem("id")},
    $.get("shoot", {"token":localStorage.getItem("token")},
        function(data) {

            console.log("oppShoot(): the result of the opponent's shot is " + data.result + ", " + data.coordPairs + ", " + data.target);

            var result = data.result;
            var coordPairs = data.coordPairs; // int[][], coordinates of the cells to be marked

            // mark the cell(s)
            if (result === "miss") {
                saveShooting(data.target[1], data.target[0], 3, 1);   // for replay (localStorage)
                new Audio("sounds/splash.wav").play();
                var coordPair = coordPairs[0];
                markSbCell(coordPair, 3);
                env.yourTurn();
            } else if (result === "hit") {
                saveShooting(data.target[1], data.target[0], 2, 1);   // for replay (localStorage)
                new Audio("sounds/thump.wav").play();
                var coordPair = coordPairs[0];
                markSbCell(coordPair, 2);
                env.oppTurn();
            } else if (result === "sink") {
                saveShooting(data.target[1], data.target[0], 1, 1);   // for replay (localStorage)
                new Audio("sounds/explosion.wav").play();
                var coordPair = data.target;
                markSbCell(coordPair, 1);
                for (var i = 0; i < coordPairs.length; i++) {
                    coordPair = coordPairs[i];
                    markSbCell(coordPair, 4);
                }
                env.oppTurn();
            }



//            console.log("got opponent's shot's result: " + shotAndResultString);
//            var shotAndResult = shotAndResultString.split(";");
//            var coords = shotAndResult[0].split(",");
//            var result = shotAndResult[1];
//            var cell = document.getElementById("side_board").rows[parseInt(coords[0])].cells[parseInt(coords[1])];
//            if (result == "sink") {
//                markSbCell(cell, 1);
//                env.oppTurn();
//            } else if (result == "hit") {
//                markSbCell(cell, 2);
//                env.oppTurn();
//            } else {
//                markSbCell(cell, 3);
//                env.yourTurn();
//            }
        }, "json");
}


//function gameOver(array) {
//    if (array.length == 0) {
//        return true;
//    } else {
//        return false;
//    }
//}

//function oppShoot() {
//    var shot = this.genOppShot();
//    console.log("opponent has made their shot: " + shot);
//    var cell = document.getElementById("side_board").rows[shot[0]].cells[shot[1]];
//
//    var hit = false;
//    console.log("opp shots to go: " + this.oppShotsToGo);
//    outer: for (var i = 0; i < this.oppShotsToGo.length; i++) {
//        //console.log("currently looking at ship: " + this.shotsToGo[i] + " with length " + this.shotsToGo[i].length );
//        for (var j = 0; j < this.oppShotsToGo[i].length; j++) {
//            //console.log("looking at coordinate: " + this.shotsToGo[i][j]);
//            if (shot[0] == this.oppShotsToGo[i][j][0] && shot[1] == this.oppShotsToGo[i][j][1]) {
//                console.log("it's a hit for opponent!");
//                // it's a hit
//                hit = true;
//                this.oppShotsToGo[i].splice(j,1);
//                console.log("current ship left: " + this.oppShotsToGo[i]);
//                if (this.oppShotsToGo[i].length == 0) {
//                    // the entire ship is destroyed
//                    env.markSbCell(cell,1);
//                    this.oppShotsToGo.splice(i,1);
//                } else {
//                    // only part of the ship is destroyed
//                    env.markSbCell(cell,2);
//                }
//                if (this.gameOver(this.oppShotsToGo)) { env.finishGame(0); } else { env.oppTurn(); }
//                break outer;
//            }
//        }
//    }
//    if (!hit) {
//        env.markSbCell(cell,3);
//        env.yourTurn();
//    }
//
//    //env.yourTurn();
//    //if (this.gameOver(this.oppShotsToGo)) { env.finishGame(0); }
//}



//function genOppShot() {
//    var index = Math.floor(Math.random()*(this.allOppShots.length-1)+1);
//    return this.allOppShots.splice(index,1)[0];
//}
